package com.clinic.aop;

import com.clinic.annoation.MyLogAnnoation;
import com.clinic.entity.Mylog;
import com.clinic.service.MyLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 日志切面类
 */


//在此切面类拦截被自定义注解annoation标注的接口请求

@Component
@Aspect  //使用aop依赖  注解表示是一个切面类
@Slf4j
public class MyLogAspect {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private MyLogService myLogService;

    // 添加切点
    //此注解 表示优先选择 join point 并收集joinpoint的上下文  pointcut可以操作所有的joinpoint
    // 此切点是一个 joinpoint 的集合
    @Pointcut("@annotation(com.clinic.annoation.MyLogAnnoation)")
    public void pointCut() {
    }

    /**
     * 环绕通知
     *
     * @param joinPoint
     * @return Object
     * @throws Throwable
     */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取切点所在的方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 从方法签名上获取将要执行的方法对象
        Method method = signature.getMethod();
        // 检查要执行的方法名前面是否需要注解
        MyLogAnnoation annotation = method.getAnnotation(MyLogAnnoation.class);
        //获取注解中的value值   也就是在注解中携带的参数
        String value = annotation.value();
        //判断value
        //创建一个日志对象
        if (!StringUtils.isEmpty(value)) {

            Mylog mylog = new Mylog();
            // 添加操作
            mylog.setLogAction(value);
            // 添加ip
            mylog.setLogIp(request.getRemoteAddr());
            // 添加操作时间
            mylog.setLogCreatetime(new Date());
            // 添加用户
            mylog.setLogUsername(request.getHeader("username"));
            // 添加日志记录
            myLogService.addLog(mylog);
            log.info("日志添加成功");
            //继续执行被注解拦截的接口方法
            Object proceed = joinPoint.proceed();//将执行目标放行，返回对象
            return proceed;
        }
        return null;
    }
}
